package org.vaadin.nf4v.core.config;

import com.vaadin.ui.Component;
import org.vaadin.nf4v.core.NavigableWindow;

import java.util.ArrayList;
import java.util.List;

/**
 * Context (application window) configuration.
 * Represents single context (and all pages in it).
 * Describes main context parameters:
 * 1. name - name of context and also part of browser url (after application context)
 * 2. window class - class of application window to instantiate
 */
public class ContextConfig extends AbstractConfig {
    private String name;
    private Class<? extends NavigableWindow> windowClass;
    private boolean mainWindow = false;
    private List<PageConfig> pages = new ArrayList<PageConfig>();
    private String theme;


    public ContextConfig(String name) {
        this.name = name;
    }

    /**
     * @return context name
     */
    public String getName() {
        return name;
    }

    /**
     * Sets context name
     *
     * @param name context name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return true if context is main context (main context is context which is shown on application context request
     *         (application root))
     */
    public boolean isMainWindow() {
        return mainWindow;
    }

    /**
     * Marking context as main is the same as addition of application window with setMainWindow in vaadin initialization.
     *
     * @param mainWindow set true to mark context as main
     */
    public void setMainWindow(boolean mainWindow) {
        this.mainWindow = mainWindow;
    }

    /**
     * @return context window class
     */
    public Class<? extends NavigableWindow> getWindowClass() {
        return windowClass;
    }

    /**
     * Sets context window class
     *
     * @param windowClass window class
     */
    public void setWindowClass(Class<? extends NavigableWindow> windowClass) {
        this.windowClass = windowClass;
    }

    /**
     * @return context theme name
     */
    public String getTheme() {
        return theme;
    }

    /**
     * @param theme context theme
     */
    public void setTheme(String theme) {
        this.theme = theme;
    }

    /**
     * Adds page into context
     *
     * @param pageConfig page configuration
     * @throws ContextConfigurationException if page with the same class is already exist
     */
    public void addPage(PageConfig pageConfig) throws ContextConfigurationException {
        for (PageConfig pc : pages) {
            if (pc.getPageClass().equals(pageConfig.getPageClass())) {
                throw new ContextConfigurationException("Page with class '" + pageConfig.getPageClass().getName() +
                        "' is already registered for context '" + name + "'");
            }
        }
        pages.add(pageConfig);
    }

    /**
     * @param uri page uri
     * @return page configuration by uri or null if not found
     */
    public PageConfig getPageByUri(String uri) {
        // todo add index
        for (PageConfig config : pages) {
            if (uri.equals(config.getUri())) {
                return config;
            }
        }
        return null;
    }

    /**
     * @param pageClass page class
     * @return page configuration by class or null if not found
     */
    public PageConfig getPageByClass(Class<? extends Component> pageClass) {
        // todo add index
        for (PageConfig config : pages) {
            if (pageClass.equals(config.getPageClass())) {
                return config;
            }
        }
        return null;
    }

    /**
     * @return home page class (for context)
     */
    public PageConfig getHomePage() {
        // todo add index
        for (PageConfig config : pages) {
            if (config.isHomePage()) {
                return config;
            }
        }
        return null;
    }

    /**
     * @return list of all context pages
     */
    public List<PageConfig> getPages() {
        return new ArrayList<PageConfig>(pages);
    }

    @Override
    public String toString() {
        return "ContextConfig{" +
                "isMainWindow=" + mainWindow +
                ", name='" + name + '\'' +
                ", windowClass=" + windowClass +
                ", pagesCount=" + pages.size() +
                ", theme='" + theme + '\'' +
                '}';
    }
}
